package porterduff

// Clear 绘图
// 公式:
//	Cr = Cs * 0 + Cd * 0
//	A = As * 0 + Ad * 0
func Clear(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Sa*0 + Da*0
	if Ra == 0 {
		Ra = 1
	}
	return (Sr*Sa*0 + Dr*Da*0) / Ra,
		(Sg*Sa*0 + Dg*Da*0) / Ra,
		(Sb*Sa*0 + Db*Da*0) / Ra,
		(Sa*0 + Da*0)
}

// Src 绘图
// 公式:
//	Cr = Cs * As + Cd * 0
//	A = As * 1 + Ad * 0
func Src(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Sa*1 + Da*0
	if Sa == 0 {
		Sa = 1
	}
	return Sr / Sa,
		Sg / Sa,
		Sb / Sa,
		Ra
}

// Dst 绘图
// 公式:
//	Cr = Cs * 0 + Cd * Ad
//	A = As * 0 + Ad * 1
func Dst(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	return Dr,
		Dg,
		Db,
		Sa*0 + Da*1
}

// SrcOver 绘图
// 公式:
//	Cr = Cs + Cd * ( 1 - As )
//	Ar = As + Ad * ( 1 -  As )
func SrcOver(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Sa + Da*(1-Sa)
	Rr = (Sr + Dr*(1-Sa)) / Ra
	Rg = (Sg + Dg*(1-Sa)) / Ra
	Rb = (Sb + Db*(1-Sa)) / Ra
	return Rr, Rg, Rb, Ra
}

// DstOver 绘图
// 公式:
//	Cr = Cs * ( 1 - Ad ) + Cd
//	Ar = As  * ( 1 -  Ad ) + Ad
func DstOver(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Da + Sa*(1-Da)
	Rr = (Dr + Sr*(1-Da)) / Ra
	Rg = (Dg + Sg*(1-Da)) / Ra
	Rb = (Db + Sb*(1-Da)) / Ra
	return Rr, Rg, Rb, Ra
}

// SrcOut 绘图
// 公式:
//	Cr = Cs * ( 1 - Ad )
//	Ar = As  * ( 1 -  Ad )
func SrcOut(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Sa * (1 - Da)
	Rr = (Sr * (1 - Da)) / Ra
	Rg = (Sg * (1 - Da)) / Ra
	Rb = (Sb * (1 - Da)) / Ra
	return Rr, Rg, Rb, Ra
}

// DstOut 绘图
// 公式:
//	Cr = Cd * ( 1 - As )
//	Ar = Ad * ( 1 -  As )
func DstOut(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Da * (1 - Sa)
	Rr = (Dr * (1 - Sa)) / Ra
	Rg = (Dg * (1 - Sa)) / Ra
	Rb = (Db * (1 - Sa)) / Ra
	return Rr, Rg, Rb, Ra
}

// SrcIn 绘图
// 公式:
//	Cs * Ad + Cd * 0
//	Ar = As * Ad
func SrcIn(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Da * (1 - Sa)
	Rr = (Dr * (1 - Sa)) / Ra
	Rg = (Dg * (1 - Sa)) / Ra
	Rb = (Db * (1 - Sa)) / Ra
	return Rr, Rg, Rb, Ra
}

// DstIn 绘图
// 公式:
//	Cs * 0 + Cd * As
//	Ar = Ad * As
func DstIn(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Da * Sa
	Rr = (Dr * Sa) / Ra
	Rg = (Dg * Sa) / Ra
	Rb = (Db * Sa) / Ra
	return Rr, Rg, Rb, Ra
}

// SrcATop 绘图
// 公式:
//	Cs*Ad + Cd * (1 - As)
//	As * Ad + Ad * (1-As)
func SrcATop(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Sa*Da + Da*(1-Sa)
	Rr = (Sr*Da + Dr*(1-Sa)) / Ra
	Rg = (Sg*Da + Dg*(1-Sa)) / Ra
	Rb = (Sb*Da + Db*(1-Sa)) / Ra
	return Rr, Rg, Rb, Ra
}

// DstATop 绘图
// 公式:
//	Cs * ( 1 - Ad ) + Cd * As
//	As * (1-Ad) + Ad * As
func DstATop(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Sa*(1-Da) + Da*Sa
	Rr = (Sr*(1-Da) + Dr*Sa) / Ra
	Rg = (Sg*(1-Da) + Dg*Sa) / Ra
	Rb = (Sb*(1-Da) + Db*Sa) / Ra
	return Rr, Rg, Rb, Ra

}

// Xor 绘图
// 公式:
//	Cs *(1-Ad)+ Cd *(1-As)
//	As *(1-Ad)+ Ad *(1-As)
func Xor(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Sa*(1-Da) + Da*(1-Sa)
	Rr = (Sr*(1-Da) + Dr*(1-Sa)) / Ra
	Rg = (Sg*(1-Da) + Dg*(1-Sa)) / Ra
	Rb = (Sb*(1-Da) + Db*(1-Sa)) / Ra
	return Rr, Rg, Rb, Ra
}

// Multiply 绘图
// 公式:
//	Cr = Cs * Cd
//	Ar = Ca * Da;
//     Ra = Sa * Da + Sa * (1-Da) + Da * (1-Sa);
//     Rr = ((Sr * Dr) + Sr * (1-Da) + Dr * (1-Sa))/(Ra);
//     Rg = ((Sg * Dg) + Sg * (1-Da) + Dg * (1-Sa))/(Ra==0?1:Ra);
//     Rb = ((Sb * Db) + Sb * (1-Da) + Db * (1-Sa))/(Ra==0?1:Ra);
func Multiply(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Ra = Sa * Da
	if Ra == 0 {
		Ra = 1
	}
	Rr = (Sr * Dr) / Ra
	Rg = (Sg * Dg) / Ra
	Rb = (Sb * Db) / Ra
	return Rr, Rg, Rb, Ra

}

// Screen 绘图
// 公式:
//	Cr = 1 - (1-Cs)(1-Cd)
//	Ar = 1 - (1-Ca)(1-Da
func Screen(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	if Ra == 0 {
		Ra = 1
	}
	Ra = 1 - (1-Sa)*(1-Da)
	Rr = (1 - (1-Sr)*(1-Dr)) / Ra
	Rg = (1 - (1-Sg)*(1-Dg)) / (Ra)
	Rb = (1 - (1-Sb)*(1-Db)) / (Ra)
	return Rr, Rg, Rb, Ra
}

// Darken 绘图
func Darken(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	Sv := Sr + Sg + Sb
	Dv := Dr + Dg + Db
	if Sv < Dv {
		Ra = Sa
	} else {
		Ra = Da
	}
	preA := Ra
	if Ra == 0 {
		preA = 1
	}

	if Sv < Dv {
		Rr = Sr
		Rg = Sg
		Rb = Sb
	} else {
		Rr = Dr
		Rg = Dg
		Rb = Db
	}
	Rr = Rr / preA
	Rg = Rg / preA
	Rb = Rb / preA
	return Rr, Rg, Rb, Ra
}

// Lighten 绘图
func Lighten(Sr, Sg, Sb, Sa, Dr, Dg, Db, Da float64) (Rr, Rg, Rb, Ra float64) {
	if Sr > Dr {
		Rr = Sr
	} else {
		Rr = Dr
	}
	if Sg > Dg {
		Rg = Sg
	} else {
		Rg = Dg
	}
	if Sb > Db {
		Rb = Sb
	} else {
		Rb = Db
	}
	if Sa > Da {
		Ra = Sa
	} else {
		Ra = Da
	}
	return Rr, Rg, Rb, Ra
}
